/*
 www.pipoisu.com
 Copyright (c) 2011.  All rights reserved.

 File     : pipo.h
 Author(s): Erez Raviv

 This program is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
 the Free Software Foundation, either version 3 of the License, or
 (at your option) any later version.

 This program is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 GNU General Public License for more details.

 You should have received a copy of the GNU General Public License
 along with this program. If not, see <http://www.gnu.org/licenses/>.
*/


#ifndef PIPO_H
#define PIPO_H


#include <inttypes.h>
#include <string.h>
#include <stdlib.h>

//#include <stddef.h>
//#include <avr/io.h>

//#include <avr/pgmspace.h>

#include <avr/eeprom.h>
//#include <avr/sleep.h>
//#include <avr/interrupt.h>

//#include <util/delay.h>
#include <util/atomic.h>
//#define pgm_read_adr(address_short) pgm_read_word(address_short)
#include <avr/wdt.h>
//#include <math.h>

//F_CPU defined in makefile


//#define PIN_OUTPUT 1
//#define PIN_INPUT  0
//#define PIN_NODEF  0

// pin definitions
//PB0 - INPUT	- PWMIN 1 / PCINT0
//PB1 - INPUT	- PWMIN 2 / PCINT1 / OC1A
//PB2 - INPUT	- PWMIN 5 / PCINT2 / OC1B
//PB3 - INPUT	- PWMIN 6 / PCINT3 / OC2A	/ MOSI
//PB4 - INPUT	- PWMIN 7 / PCINT4			/ MISO
//PB5 - INPUT	- PWMIN 8 / PCINT5			/ SCK
//PB6 - XTAL 1
//PB7 - XTAL 2

//PC0 - INPUT	- PWMIN 3 / PCINT 8
//PC1 - INPUT	- PWMIN 4 / PCINT 9
//PC2 - OUTPUT	- Red LED
//PC3 - OUTPUT	- Green LED
//PC4 - TWI		- SDA
//PC5 - TWI		- SCL
//PC6 - RESET
//PC7 - ?

//PD0 - OUTPUT	- PWMOUT 1 / PCINT 16	/ RXD
//PD1 - OUTPUT	- PWMOUT 2 / PCINT 17	/ TXD		
//PD2 - OUTPUT	- PWMOUT 3 / PCINT 18
//PD3 - OUTPUT	- PWMOUT 4 / PCINT 19	/ OC2B	
//PD4 - OUTPUT	- PWMOUT 5 / PCINT 20
//PD5 - OUTPUT	- PWMOUT 6 / PCINT 21	/ OC0B	
//PD6 - OUTPUT	- PWMOUT 7 / PCINT 22	/ OC0A	
//PD7 - OUTPUT	- PWMOUT 8 / PCINT 23


//LED definitions
#define PORT_LED_RED      PORTC
#define BIT_LED_RED       (1<<PC2)
#define PORT_LED_GREEN    PORTC
#define BIT_LED_GREEN     (1<<PC3)

//PWM_IN definitions
#define PWM_IN_MASK  ((PINB & 0x03) | (((PINB & 0x3C) | (PINC & 0x03))<<2))
#define PCMSK0_BITS  ((1<<PCINT0) | (1<<PCINT1) | (1<<PCINT2) | (1<<PCINT3) | (1<<PCINT4) | (1<<PCINT5)) //bits on port B
#define PCMSK1_BITS  ((1<<PCINT8) | (1<<PCINT9))  //bits on port C
#define PCMSK2_BITS  0 // no bits set on portd
#define PCICR_BITS   ((1<<PCIE0) | (1<<PCIE1)) //enable PC interrupt on ports B and C

#define PORT_B_SETUP	(0x00)  // 0..5 inputs
#define PORT_B_INIT		(0x3F)  // set up pullups
#define PORT_C_SETUP	(0x0C)  // 2 leds are outputs
#define PORT_C_INIT		(0x03)  // DO NOT ENABLE PULLUPS ON SDA/SCL!
#define PORT_D_SETUP	(0xFF)  // all outputs
#define PORT_D_INIT		(0x00)  //

#define LED_RED_ON      PORT_LED_RED	|=  BIT_LED_RED
#define LED_RED_OFF     PORT_LED_RED	&= ~BIT_LED_RED
#define LED_RED_FLIP    PORT_LED_RED	^=  BIT_LED_RED
#define LED_RED_IS_ON   (PORT_LED_RED	&	BIT_LED_RED)
#define LED_GREEN_ON    PORT_LED_GREEN	|=  BIT_LED_GREEN
#define LED_GREEN_OFF   PORT_LED_GREEN	&= ~BIT_LED_GREEN
#define LED_GREEN_FLIP  PORT_LED_GREEN	^=  BIT_LED_GREEN
#define LED_GREEN_IS_ON (PORT_LED_GREEN	&	BIT_LED_GREEN)

#define RESX_SHIFT      10
#define RESX            (1<<RESX_SHIFT)
#define RESXf           (1024.0f)
#define RESXl			1024l
#define RESXu			1024u
#define RESXul			1024ul
#define RESKul			100ul

#define TICKS_PER_MSEC  2000        // (16000/8)
#define TICKS_PER_SEC   2000000.0f  // (16000/8 * 1000) = 2 milion ticks

//#define PWM_OUT_FRAME   (TICKS_PER_MSEC*5/2)  // 2.5 msec -> 400Hz
#define PWM_MIDFRAME    (TICKS_PER_MSEC*3/2)  // 1.5 msec 
#define PWM_MAX         (PWM_MIDFRAME + RESX)
#define PWM_MIN         (PWM_MIDFRAME - RESX)
#define PWM_STICK_MIN   (PWM_MIDFRAME - (RESX*5/4)) // allow for +/- 125% from TX
#define PWM_STICK_MAX   (PWM_MIDFRAME + (RESX*5/4))


#define STICK_LIMIT		150		// defines the point at which a stick is considered to be @ max travel
#define STICK_HI		(RESX-STICK_LIMIT)	//defines stick @ max
#define STICK_LO		(STICK_LIMIT-RESX)	//defines stick @ min

#define NUMPPM_IN		8
#define NUMPPM_OUT		8    // number of output ppm channels

//#define NUM_PPM		8
//number of real outputchannels CH1-CH16
#define NUM_CHNOUT		16
///number of real input channels (1-9) plus virtual input channels X1-X4
#define PPM_BASE		MIX_CYC3
#define CHOUT_BASE		(PPM_BASE+NUMPPM_OUT)


#define NUM_XCHNRAW		(CHOUT_BASE+NUM_CHNOUT)//gh##+NUM_TELEMETRY) // NUMCH + P1P2P3+ AIL/RUD/ELE/THR + MAX/FULL + CYC1/CYC2/CYC3
///number of real output channels (CH1-CH8) plus virtual output channels X1-X4
#define NUM_XCHNOUT		(NUM_CHNOUT) //(NUM_CHNOUT)//+NUM_VIRT)


#define NUM_CSW			4

#define CALIB_SAMPLES	10  //sensor samples for offset.   Each sample takes 0.1sec (100ms) at startup.
#define STARTUP_DELAY	500 //500 msec startup delay

#define G25MSEC_SPAN	(TICKS_PER_MSEC * 25L) // 25msec timer


/*************************************************************************
 Macros
*************************************************************************/
#define MIN(a,b)           ( ((a)<(b)) ? (a) : (b) )
#define MAX(a,b)           ( ((a)>(b)) ? (a) : (b) )
#define MINMAX(x,min,max)  ( MIN(MAX((x),(min)),(max)) )
#define INTMINMAX(x)       ( MINMAX(x,-0x7FFF,0x7FFF)  )
#define CONSTRAIN(x,a)     ( MINMAX(x,-(a),(a)) )

#define FASTDIV_RESX(x)    ( (x)>>RESX_SHIFT )
#define UINT_LESSTHAN(a,b) ( ((a)-(b)) & 0x8000 ) // true if b>a
#define SWAP(a,b)          ( ((a) ^ (b)) && ((b) ^= (a) ^= (b), (a) ^= (b)) )


#include "eepromData.h"

extern pipoData_t pipoData;

extern float attitude[3];
extern float deltaT;

extern uint8_t magnetometer;
extern volatile uint16_t g25msec;

extern volatile uint8_t flashRedLed;


#endif // PIPO_H
